{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e6067a2f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# | default_exp _cli_docs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ff086fc9",
   "metadata": {},
   "outputs": [],
   "source": [
    "# | export\n",
    "\n",
    "import asyncio\n",
    "import platform\n",
    "import signal\n",
    "import socketserver\n",
    "from http.server import SimpleHTTPRequestHandler\n",
    "from pathlib import Path\n",
    "from types import FrameType\n",
    "from typing import *\n",
    "\n",
    "import typer\n",
    "\n",
    "from fastkafka._components.docs_dependencies import (\n",
    "    _check_npm_with_local,\n",
    "    _install_docs_npm_deps,\n",
    "    _install_node,\n",
    ")\n",
    "from fastkafka._components.helpers import _import_from_string, change_dir\n",
    "from fastkafka._components.logger import get_logger"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7308ae66",
   "metadata": {},
   "outputs": [],
   "source": [
    "import time\n",
    "\n",
    "from typer.testing import CliRunner\n",
    "\n",
    "from fastkafka._components.logger import suppress_timestamps\n",
    "from fastkafka._components.test_dependencies import generate_app_in_tmp\n",
    "from fastkafka._server import terminate_asyncio_process"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2cf6183c",
   "metadata": {},
   "outputs": [],
   "source": [
    "# | notest\n",
    "\n",
    "# allows async calls in notebooks\n",
    "\n",
    "import nest_asyncio"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6c873369",
   "metadata": {},
   "outputs": [],
   "source": [
    "# | notest\n",
    "\n",
    "nest_asyncio.apply()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1d072658",
   "metadata": {},
   "outputs": [],
   "source": [
    "# | export\n",
    "\n",
    "logger = get_logger(__name__)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7da7962a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[INFO] __main__: ok\n"
     ]
    }
   ],
   "source": [
    "suppress_timestamps()\n",
    "logger = get_logger(__name__, level=20)\n",
    "logger.info(\"ok\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8f1b231d",
   "metadata": {},
   "outputs": [],
   "source": [
    "runner = CliRunner()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9b11fc9c",
   "metadata": {},
   "outputs": [],
   "source": [
    "# | export\n",
    "\n",
    "_docs_app = typer.Typer(help=\"Commands for managing FastKafka app documentation\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bb880142",
   "metadata": {},
   "outputs": [],
   "source": [
    "# | export\n",
    "\n",
    "\n",
    "@_docs_app.command(\n",
    "    \"install_deps\",\n",
    "    help=\"Installs dependencies for FastKafka documentation generation\",\n",
    ")\n",
    "def docs_install_deps() -> None:\n",
    "    \"\"\"\n",
    "    Installs dependencies for FastKafka documentation generation.\n",
    "\n",
    "    Raises:\n",
    "        typer.Abort: If the user chooses not to install NodeJS and npm locally.\n",
    "    \"\"\"\n",
    "    try:\n",
    "        _check_npm_with_local()\n",
    "    except Exception as e:\n",
    "        typer.secho(f\"Unexpected internal error: {e}\", err=True, fg=typer.colors.RED)\n",
    "        install_confirm = typer.confirm(\n",
    "            \"npm not found or version is too low, do you want us to install the NodeJS and npm locally?\"\n",
    "        )\n",
    "        if install_confirm is False:\n",
    "            print(\"Not installing NodeJS and npm locally, exiting..\")\n",
    "            raise typer.Abort()\n",
    "        else:\n",
    "            _install_node()\n",
    "    asyncio.run(_install_docs_npm_deps())\n",
    "\n",
    "\n",
    "@_docs_app.command(\n",
    "    \"generate\",\n",
    "    help=\"Generates documentation for a FastKafka application\",\n",
    ")\n",
    "def generate_docs(\n",
    "    root_path: Optional[str] = typer.Option(\n",
    "        default=None,\n",
    "        help=\"root path under which documentation will be created; default is current directory\",\n",
    "        show_default=False,\n",
    "    ),\n",
    "    app: str = typer.Argument(\n",
    "        ...,\n",
    "        help=\"input in the form of 'path:app', where **path** is the path to a python file and **app** is an object of type **FastKafka**.\",\n",
    "    ),\n",
    ") -> None:\n",
    "    \"\"\"\n",
    "    Generates documentation for a FastKafka application.\n",
    "\n",
    "    Args:\n",
    "        root_path: The root path under which the documentation will be created.\n",
    "            Default is the current directory.\n",
    "        app: Input in the form of 'path:app', where **path** is the path to a python\n",
    "            file and **app** is an object of type **FastKafka**.\n",
    "\n",
    "    Raises:\n",
    "        typer.Exit: If there is an unexpected internal error.\n",
    "    \"\"\"\n",
    "    try:\n",
    "        application = _import_from_string(app)\n",
    "        if root_path is not None:\n",
    "            application._root_path = Path(root_path)\n",
    "            application._asyncapi_path = application._root_path / \"asyncapi\"\n",
    "\n",
    "        application.skip_docs = False\n",
    "        application.create_docs()\n",
    "    except Exception as e:\n",
    "        typer.secho(f\"Unexpected internal error: {e}\", err=True, fg=typer.colors.RED)\n",
    "        raise typer.Exit(1)\n",
    "\n",
    "\n",
    "@_docs_app.command(\n",
    "    \"serve\",\n",
    "    help=\"Generates and serves documentation for a FastKafka application\",\n",
    ")\n",
    "def serve_docs(\n",
    "    root_path: str = typer.Option(\n",
    "        default=None,\n",
    "        help=\"root path under which documentation will be created; default is current directory\",\n",
    "        show_default=False,\n",
    "    ),\n",
    "    bind: str = typer.Option(\"127.0.0.1\", help=\"Some info\"),\n",
    "    port: int = typer.Option(8000, help=\"Some info\"),\n",
    "    app: str = typer.Argument(\n",
    "        ...,\n",
    "        help=\"input in the form of 'path:app', where **path** is the path to a python file and **app** is an object of type **FastKafka**.\",\n",
    "    ),\n",
    ") -> None:\n",
    "    \"\"\"\n",
    "    Generates and serves documentation for a FastKafka application.\n",
    "\n",
    "    Args:\n",
    "        root_path: The root path under which the documentation will be created.\n",
    "            Default is the current directory.\n",
    "        bind: The IP address to bind the server to. Default is '127.0.0.1'.\n",
    "        port: The port number to bind the server to. Default is 8000.\n",
    "        app: Input in the form of 'path:app', where **path** is the path to a python\n",
    "            file and **app** is an object of type **FastKafka**.\n",
    "\n",
    "    Raises:\n",
    "        typer.Exit: If there is an unexpected internal error.\n",
    "    \"\"\"\n",
    "    try:\n",
    "        application = _import_from_string(app)\n",
    "        if root_path is not None:\n",
    "            application._root_path = Path(root_path)\n",
    "            application._asyncapi_path = application._root_path / \"asyncapi\"\n",
    "\n",
    "        application.create_docs()\n",
    "        with change_dir(str(application._asyncapi_path / \"docs\")):\n",
    "            server_address = (bind, port)\n",
    "            handler = SimpleHTTPRequestHandler\n",
    "\n",
    "            d = {\"should_stop\": False}\n",
    "\n",
    "            def sigint_handler(\n",
    "                signal: int, frame: Optional[FrameType], d: Dict[str, bool] = d\n",
    "            ) -> None:\n",
    "                d[\"should_stop\"] = True\n",
    "\n",
    "            signal.signal(signal.SIGINT, sigint_handler)\n",
    "            signal.signal(signal.SIGTERM, sigint_handler)\n",
    "            if platform.system() == \"Windows\":\n",
    "                signal.signal(signal.SIGBREAK, sigint_handler) # type: ignore\n",
    "\n",
    "            with socketserver.TCPServer(server_address, handler) as httpd:\n",
    "                httpd.timeout = 0.1\n",
    "                typer.secho(\n",
    "                    f\"Serving documentation on http://{server_address[0]}:{server_address[1]}\"\n",
    "                )\n",
    "                while not d[\"should_stop\"]:\n",
    "                    httpd.handle_request()\n",
    "                typer.secho(f\"Interupting serving of documentation and cleaning up...\")\n",
    "    except Exception as e:\n",
    "        typer.secho(f\"Unexpected internal error: {e}\", err=True, fg=typer.colors.RED)\n",
    "        raise typer.Exit(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "81371542",
   "metadata": {},
   "outputs": [],
   "source": [
    "# | notest\n",
    "\n",
    "! nbdev_export"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6f578155",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">                                                                                                                   </span>\n",
       "<span style=\"font-weight: bold\"> </span><span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\">Usage: </span><span style=\"font-weight: bold\">root install_deps [OPTIONS]                                                                                </span>\n",
       "<span style=\"font-weight: bold\">                                                                                                                   </span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1m                                                                                                                   \u001b[0m\n",
       "\u001b[1m \u001b[0m\u001b[1;33mUsage: \u001b[0m\u001b[1mroot install_deps [OPTIONS]\u001b[0m\u001b[1m                                                                               \u001b[0m\u001b[1m \u001b[0m\n",
       "\u001b[1m                                                                                                                   \u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"> Installs dependencies for FastKafka documentation generation                                                      \n",
       "                                                                                                                   \n",
       "</pre>\n"
      ],
      "text/plain": [
       " Installs dependencies for FastKafka documentation generation                                                      \n",
       "                                                                                                                   \n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">╭─ Options ───────────────────────────────────────────────────────────────────────────────────────────────────────╮</span>\n",
       "<span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">│</span> <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">--help</span>          Show this message and exit.                                                                     <span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">│</span>\n",
       "<span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[2m╭─\u001b[0m\u001b[2m Options \u001b[0m\u001b[2m──────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\u001b[2m─╮\u001b[0m\n",
       "\u001b[2m│\u001b[0m \u001b[1;36m-\u001b[0m\u001b[1;36m-help\u001b[0m          Show this message and exit.                                                                     \u001b[2m│\u001b[0m\n",
       "\u001b[2m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "result = runner.invoke(_docs_app, [\"install_deps\", \"--help\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "12c1ad43",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[INFO] fastkafka._components.docs_dependencies: AsyncAPI generator installed\n"
     ]
    }
   ],
   "source": [
    "result = runner.invoke(_docs_app, [\"install_deps\"])\n",
    "assert result.exit_code in [0,1], result.exit_code"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8d436308",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">                                                                                                                   </span>\n",
       "<span style=\"font-weight: bold\"> </span><span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\">Usage: </span><span style=\"font-weight: bold\">root generate [OPTIONS] APP                                                                                </span>\n",
       "<span style=\"font-weight: bold\">                                                                                                                   </span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1m                                                                                                                   \u001b[0m\n",
       "\u001b[1m \u001b[0m\u001b[1;33mUsage: \u001b[0m\u001b[1mroot generate [OPTIONS] APP\u001b[0m\u001b[1m                                                                               \u001b[0m\u001b[1m \u001b[0m\n",
       "\u001b[1m                                                                                                                   \u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"> Generates documentation for a FastKafka application                                                               \n",
       "                                                                                                                   \n",
       "</pre>\n"
      ],
      "text/plain": [
       " Generates documentation for a FastKafka application                                                               \n",
       "                                                                                                                   \n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">╭─ Arguments ─────────────────────────────────────────────────────────────────────────────────────────────────────╮</span>\n",
       "<span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">│</span> <span style=\"color: #800000; text-decoration-color: #800000\">*</span>    app      <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\">TEXT</span>  input in the form of 'path:app', where **path** is the path to a python file and **app** is <span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">│</span>\n",
       "<span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">│</span>                     an object of type **FastKafka**.                                                            <span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">│</span>\n",
       "<span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">│</span>                     <span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">[default: None]                                                                            </span> <span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">│</span>\n",
       "<span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">│</span>                     <span style=\"color: #bf7f7f; text-decoration-color: #bf7f7f\">[required]                                                                                 </span> <span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">│</span>\n",
       "<span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[2m╭─\u001b[0m\u001b[2m Arguments \u001b[0m\u001b[2m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\u001b[2m─╮\u001b[0m\n",
       "\u001b[2m│\u001b[0m \u001b[31m*\u001b[0m    app      \u001b[1;33mTEXT\u001b[0m  input in the form of 'path:app', where **path** is the path to a python file and **app** is \u001b[2m│\u001b[0m\n",
       "\u001b[2m│\u001b[0m                     an object of type **FastKafka**.                                                            \u001b[2m│\u001b[0m\n",
       "\u001b[2m│\u001b[0m                     \u001b[2m[default: None]                                                                            \u001b[0m \u001b[2m│\u001b[0m\n",
       "\u001b[2m│\u001b[0m                     \u001b[2;31m[required]                                                                                 \u001b[0m \u001b[2m│\u001b[0m\n",
       "\u001b[2m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">╭─ Options ───────────────────────────────────────────────────────────────────────────────────────────────────────╮</span>\n",
       "<span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">│</span> <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">--root-path</span>        <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\">TEXT</span>  root path under which documentation will be created <span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">[default: .]</span>                       <span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">│</span>\n",
       "<span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">│</span> <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">--help</span>             <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\">    </span>  Show this message and exit.                                                            <span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">│</span>\n",
       "<span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[2m╭─\u001b[0m\u001b[2m Options \u001b[0m\u001b[2m──────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\u001b[2m─╮\u001b[0m\n",
       "\u001b[2m│\u001b[0m \u001b[1;36m-\u001b[0m\u001b[1;36m-root\u001b[0m\u001b[1;36m-path\u001b[0m        \u001b[1;33mTEXT\u001b[0m  root path under which documentation will be created \u001b[2m[default: .]\u001b[0m                       \u001b[2m│\u001b[0m\n",
       "\u001b[2m│\u001b[0m \u001b[1;36m-\u001b[0m\u001b[1;36m-help\u001b[0m             \u001b[1;33m    \u001b[0m  Show this message and exit.                                                            \u001b[2m│\u001b[0m\n",
       "\u001b[2m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "result = runner.invoke(_docs_app, [\"generate\", \"--help\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d2c16070",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[INFO] fastkafka._components.asyncapi: Old async specifications at '/tmp/tmpqvalk_fi/asyncapi/spec/asyncapi.yml' does not exist.\n",
      "[INFO] fastkafka._components.asyncapi: New async specifications generated at: '/tmp/tmpqvalk_fi/asyncapi/spec/asyncapi.yml'\n",
      "[INFO] fastkafka._components.asyncapi: Async docs generated at 'asyncapi/docs'\n",
      "[INFO] fastkafka._components.asyncapi: Output of '$ npx -y -p @asyncapi/generator ag asyncapi/spec/asyncapi.yml @asyncapi/html-template -o asyncapi/docs --force-write'\u001b[32m\n",
      "\n",
      "Done! ✨\u001b[0m\n",
      "\u001b[33mCheck out your shiny new generated files at \u001b[0m\u001b[35m/tmp/tmpqvalk_fi/asyncapi/docs\u001b[0m\u001b[33m.\u001b[0m\n",
      "\n",
      "\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "with generate_app_in_tmp() as import_str:\n",
    "    result = runner.invoke(_docs_app, [\"generate\", import_str])\n",
    "    typer.echo(result.output)\n",
    "    assert result.exit_code in [0,1], result.exit_code\n",
    "\n",
    "    result = runner.invoke(_docs_app, [\"generate\", import_str])\n",
    "    typer.echo(result.output)\n",
    "    assert result.exit_code in [0,1], result.exit_code"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "27500e8b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">                                                                                                                   </span>\n",
       "<span style=\"font-weight: bold\"> </span><span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\">Usage: </span><span style=\"font-weight: bold\">root serve [OPTIONS] APP                                                                                   </span>\n",
       "<span style=\"font-weight: bold\">                                                                                                                   </span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1m                                                                                                                   \u001b[0m\n",
       "\u001b[1m \u001b[0m\u001b[1;33mUsage: \u001b[0m\u001b[1mroot serve [OPTIONS] APP\u001b[0m\u001b[1m                                                                                  \u001b[0m\u001b[1m \u001b[0m\n",
       "\u001b[1m                                                                                                                   \u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"> Generates and serves documentation for a FastKafka application                                                    \n",
       "                                                                                                                   \n",
       "</pre>\n"
      ],
      "text/plain": [
       " Generates and serves documentation for a FastKafka application                                                    \n",
       "                                                                                                                   \n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">╭─ Arguments ─────────────────────────────────────────────────────────────────────────────────────────────────────╮</span>\n",
       "<span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">│</span> <span style=\"color: #800000; text-decoration-color: #800000\">*</span>    app      <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\">TEXT</span>  input in the form of 'path:app', where **path** is the path to a python file and **app** is <span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">│</span>\n",
       "<span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">│</span>                     an object of type **FastKafka**.                                                            <span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">│</span>\n",
       "<span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">│</span>                     <span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">[default: None]                                                                            </span> <span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">│</span>\n",
       "<span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">│</span>                     <span style=\"color: #bf7f7f; text-decoration-color: #bf7f7f\">[required]                                                                                 </span> <span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">│</span>\n",
       "<span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[2m╭─\u001b[0m\u001b[2m Arguments \u001b[0m\u001b[2m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\u001b[2m─╮\u001b[0m\n",
       "\u001b[2m│\u001b[0m \u001b[31m*\u001b[0m    app      \u001b[1;33mTEXT\u001b[0m  input in the form of 'path:app', where **path** is the path to a python file and **app** is \u001b[2m│\u001b[0m\n",
       "\u001b[2m│\u001b[0m                     an object of type **FastKafka**.                                                            \u001b[2m│\u001b[0m\n",
       "\u001b[2m│\u001b[0m                     \u001b[2m[default: None]                                                                            \u001b[0m \u001b[2m│\u001b[0m\n",
       "\u001b[2m│\u001b[0m                     \u001b[2;31m[required]                                                                                 \u001b[0m \u001b[2m│\u001b[0m\n",
       "\u001b[2m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">╭─ Options ───────────────────────────────────────────────────────────────────────────────────────────────────────╮</span>\n",
       "<span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">│</span> <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">--root-path</span>        <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\">TEXT   </span>  root path under which documentation will be created <span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">[default: .]</span>                    <span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">│</span>\n",
       "<span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">│</span> <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">--bind</span>             <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\">TEXT   </span>  Some info <span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">[default: 127.0.0.1]</span>                                                      <span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">│</span>\n",
       "<span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">│</span> <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">--port</span>             <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\">INTEGER</span>  Some info <span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">[default: 8000]</span>                                                           <span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">│</span>\n",
       "<span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">│</span> <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">--help</span>             <span style=\"color: #808000; text-decoration-color: #808000; font-weight: bold\">       </span>  Show this message and exit.                                                         <span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">│</span>\n",
       "<span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[2m╭─\u001b[0m\u001b[2m Options \u001b[0m\u001b[2m──────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\u001b[2m─╮\u001b[0m\n",
       "\u001b[2m│\u001b[0m \u001b[1;36m-\u001b[0m\u001b[1;36m-root\u001b[0m\u001b[1;36m-path\u001b[0m        \u001b[1;33mTEXT   \u001b[0m  root path under which documentation will be created \u001b[2m[default: .]\u001b[0m                    \u001b[2m│\u001b[0m\n",
       "\u001b[2m│\u001b[0m \u001b[1;36m-\u001b[0m\u001b[1;36m-bind\u001b[0m             \u001b[1;33mTEXT   \u001b[0m  Some info \u001b[2m[default: 127.0.0.1]\u001b[0m                                                      \u001b[2m│\u001b[0m\n",
       "\u001b[2m│\u001b[0m \u001b[1;36m-\u001b[0m\u001b[1;36m-port\u001b[0m             \u001b[1;33mINTEGER\u001b[0m  Some info \u001b[2m[default: 8000]\u001b[0m                                                           \u001b[2m│\u001b[0m\n",
       "\u001b[2m│\u001b[0m \u001b[1;36m-\u001b[0m\u001b[1;36m-help\u001b[0m             \u001b[1;33m       \u001b[0m  Show this message and exit.                                                         \u001b[2m│\u001b[0m\n",
       "\u001b[2m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "result = runner.invoke(_docs_app, [\"serve\", \"--help\"])"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "python3",
   "language": "python",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
